# Untitled - By: lenovo - Fri Jul 26 2024


import sensor
import image
import random
import machine
from pyb import UART
from pyb import LED


sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time=2000)


# 创建串口通信对象
uart = UART(3, 115200, bits=8, parity=None, stop=1)
# 创建image对象
img = sensor.snapshot()
# led灯光
led = LED(random.randint(1, 3))

def LED_Show():
    global led
    led.off()
    led = LED(random.randint(1, 3))
    led.on()

def LED_Off():
    global led
    led.off()


def DrawRecognizeXY(corners):
    global img
    img.draw_circle(corners[0][0], corners[0][1], 5, color=(255, 0, 0))
    img.draw_circle(corners[1][0], corners[1][1], 5, color=(0, 255, 0))
    img.draw_circle(corners[2][0], corners[2][1], 5, color=(0, 0, 255))
    img.draw_circle(corners[3][0], corners[3][1], 5, color=(255, 255, 255))


# 发送坐标数据
def UART_SendRecognizeXY(recognize):
    global uart
    # 从左上角开始顺时针返回坐标
    corners = [[recognize[0], recognize[1]], [recognize[0] + recognize[2], recognize[1]], [recognize[0] + recognize[2], recognize[1] + recognize[3]], [recognize[0], recognize[1] + recognize[3]]]
    for XY in corners:
        sendarray = str(XY[0]) + ' ' + str(XY[1])
        uart.write(sendarray)
        print(sendarray)
    print('')
    DrawRecognizeXY(corners)


# 加载人脸检测HaarCascade。 这是OpenMV Cam可以使用下面的find_features（）方法来检测人脸的对象
# 默认情况下，HaarCascade的所有阶段都被加载。 但是，您可以调整阶段的数量来加快处理速度，但要以准确性为代价。
# HaarCascade的前面有25个阶段。
face_cascade = image.HaarCascade("frontalface", stages=25)

while True:
    img = sensor.snapshot()
    # 去畸变
    img.lens_corr(strength=1.8, zoom=1.0)

    # Threshold是介于0.0-1.0的阈值，较低值会同时提高检出率和假阳性率。相反，较高值会同时降低检出率和假阳性率。
    # scale是一个必须大于1.0的浮点数。较高的比例因子运行更快，但其图像匹配相应较差。理想值介于1.35-1.5之间。
    # scale控制匹配比例，使您可以检测较小的脸部。
    faces = img.find_features(face_cascade, threshold=0.5, scale_factor=1.5)

    if faces:
        LED_Show()
        for recognize in faces:
            img.draw_rectangle(recognize)
            UART_SendRecognizeXY(recognize)
    else:
        LED_Off()
